#include <hxcpp.h>

#ifndef INCLUDED_IntHash
#include <IntHash.h>
#endif
#ifndef INCLUDED_format_tools_HuffTools
#include <format/tools/HuffTools.h>
#endif
#ifndef INCLUDED_format_tools_Huffman
#include <format/tools/Huffman.h>
#endif
namespace format{
namespace tools{

Void HuffTools_obj::__construct()
{
{
}
;
	return null();
}

HuffTools_obj::~HuffTools_obj() { }

Dynamic HuffTools_obj::__CreateEmpty() { return  new HuffTools_obj; }
hx::ObjectPtr< HuffTools_obj > HuffTools_obj::__new()
{  hx::ObjectPtr< HuffTools_obj > result = new HuffTools_obj();
	result->__construct();
	return result;}

Dynamic HuffTools_obj::__Create(hx::DynamicArray inArgs)
{  hx::ObjectPtr< HuffTools_obj > result = new HuffTools_obj();
	result->__construct();
	return result;}

int HuffTools_obj::treeDepth( ::format::tools::Huffman t){
	HX_SOURCE_PUSH("HuffTools_obj::treeDepth")
	struct _Function_1_1{
		inline static int Block( ::format::tools::Huffman &t,::format::tools::HuffTools_obj *__this){
			{
				HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",45)
				{
::format::tools::Huffman _switch_1 = (t);
					switch((_switch_1)->GetIndex()){
						case 0: {
							HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",46)
							return (int)0;
						}
						;break;
						case 2: {
							HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",47)
							return hx::Throw (HX_CSTRING("assert"));
						}
						;break;
						case 1: {
							::format::tools::Huffman b = _switch_1->__Param(1);
							::format::tools::Huffman a = _switch_1->__Param(0);
{
								HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",49)
								int da = __this->treeDepth(a);
								HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",50)
								int db = __this->treeDepth(b);
								HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",51)
								return ((int)1 + ((  (((da < db))) ? int(da) : int(db) )));
							}
						}
						;break;
					}
				}
			}
			return null();
		}
	};
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",44)
	return _Function_1_1::Block(t,this);
}


HX_DEFINE_DYNAMIC_FUNC1(HuffTools_obj,treeDepth,return )

::format::tools::Huffman HuffTools_obj::treeCompress( ::format::tools::Huffman t){
	HX_SOURCE_PUSH("HuffTools_obj::treeCompress")
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",56)
	int d = this->treeDepth(t);
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",57)
	if (((d == (int)0))){
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",58)
		return t;
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",59)
	if (((d == (int)1))){
		struct _Function_2_1{
			inline static ::format::tools::Huffman Block( ::format::tools::Huffman &t,::format::tools::HuffTools_obj *__this){
				{
					HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",60)
					{
::format::tools::Huffman _switch_2 = (t);
						switch((_switch_2)->GetIndex()){
							case 1: {
								::format::tools::Huffman b = _switch_2->__Param(1);
								::format::tools::Huffman a = _switch_2->__Param(0);
{
									HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",61)
									return ::format::tools::Huffman_obj::NeedBit(__this->treeCompress(a),__this->treeCompress(b));
								}
							}
							;break;
							default: {
								HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",62)
								return hx::Throw (HX_CSTRING("assert"));
							}
						}
					}
				}
				return null();
			}
		};
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",60)
		return _Function_2_1::Block(t,this);
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",64)
	int size = (int((int)1) << int(d));
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",65)
	Array< ::format::tools::Huffman > table = Array_obj< ::format::tools::Huffman >::__new();
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",66)
	{
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",66)
		int _g = (int)0;
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",66)
		while(((_g < size))){
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",66)
			int i = (_g)++;
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",67)
			table->push(::format::tools::Huffman_obj::Found((int)-1));
		}
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",68)
	this->treeWalk(table,(int)0,(int)0,d,t);
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",69)
	return ::format::tools::Huffman_obj::NeedBits(d,table);
}


HX_DEFINE_DYNAMIC_FUNC1(HuffTools_obj,treeCompress,return )

Void HuffTools_obj::treeWalk( Array< ::format::tools::Huffman > table,int p,int cd,int d,::format::tools::Huffman t){
{
		HX_SOURCE_PUSH("HuffTools_obj::treeWalk")
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",72)
		{
::format::tools::Huffman _switch_3 = (t);
			switch((_switch_3)->GetIndex()){
				case 1: {
					::format::tools::Huffman b = _switch_3->__Param(1);
					::format::tools::Huffman a = _switch_3->__Param(0);
{
						HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",74)
						if (((d > (int)0))){
							HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",76)
							this->treeWalk(table,p,(cd + (int)1),(d - (int)1),a);
							HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",77)
							this->treeWalk(table,(int(p) | int((int((int)1) << int(cd)))),(cd + (int)1),(d - (int)1),b);
						}
						else{
							HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",79)
							table[p] = this->treeCompress(t);
						}
					}
				}
				;break;
				default: {
					HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",80)
					table[p] = this->treeCompress(t);
				}
			}
		}
	}
return null();
}


HX_DEFINE_DYNAMIC_FUNC5(HuffTools_obj,treeWalk,(void))

::format::tools::Huffman HuffTools_obj::treeMake( ::IntHash bits,int maxbits,int v,int len){
	HX_SOURCE_PUSH("HuffTools_obj::treeMake")
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",86)
	if (((len > maxbits))){
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",86)
		hx::Throw (HX_CSTRING("Invalid huffman"));
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",87)
	int idx = (int((int(v) << int((int)5))) | int(len));
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",88)
	if ((bits->exists(idx))){
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",89)
		return ::format::tools::Huffman_obj::Found(bits->get(idx));
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",90)
	hx::ShlEq(v,(int)1);
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",91)
	hx::AddEq(len,(int)1);
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",92)
	return ::format::tools::Huffman_obj::NeedBit(this->treeMake(bits,maxbits,v,len),this->treeMake(bits,maxbits,(int(v) | int((int)1)),len));
}


HX_DEFINE_DYNAMIC_FUNC4(HuffTools_obj,treeMake,return )

::format::tools::Huffman HuffTools_obj::make( Array< int > lengths,int pos,int nlengths,int maxbits){
	HX_SOURCE_PUSH("HuffTools_obj::make")
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",96)
	Array< int > counts = Array_obj< int >::__new();
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",97)
	Array< int > tmp = Array_obj< int >::__new();
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",98)
	if (((maxbits > (int)32))){
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",98)
		hx::Throw (HX_CSTRING("Invalid huffman"));
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",99)
	{
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",99)
		int _g = (int)0;
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",99)
		while(((_g < maxbits))){
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",99)
			int i = (_g)++;
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",100)
			counts->push((int)0);
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",101)
			tmp->push((int)0);
		}
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",103)
	{
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",103)
		int _g = (int)0;
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",103)
		while(((_g < nlengths))){
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",103)
			int i = (_g)++;
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",104)
			int p = lengths->__get((i + pos));
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",105)
			if (((p >= maxbits))){
				HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",105)
				hx::Throw (HX_CSTRING("Invalid huffman"));
			}
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",106)
			(counts[p])++;
		}
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",108)
	int code = (int)0;
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",109)
	{
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",109)
		int _g1 = (int)1;
		int _g = (maxbits - (int)1);
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",109)
		while(((_g1 < _g))){
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",109)
			int i = (_g1)++;
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",110)
			code = (int((code + counts->__get(i))) << int((int)1));
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",111)
			tmp[i] = code;
		}
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",113)
	::IntHash bits = ::IntHash_obj::__new();
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",114)
	{
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",114)
		int _g = (int)0;
		HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",114)
		while(((_g < nlengths))){
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",114)
			int i = (_g)++;
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",115)
			int l = lengths->__get((i + pos));
			HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",116)
			if (((l != (int)0))){
				HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",117)
				int n = tmp->__get((l - (int)1));
				HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",118)
				tmp[(l - (int)1)] = (n + (int)1);
				HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",119)
				bits->set((int((int(n) << int((int)5))) | int(l)),i);
			}
		}
	}
	HX_SOURCE_POS("/usr/lib/haxe/lib/format/1,22/format/tools/Huffman.hx",122)
	return this->treeCompress(::format::tools::Huffman_obj::NeedBit(this->treeMake(bits,maxbits,(int)0,(int)1),this->treeMake(bits,maxbits,(int)1,(int)1)));
}


HX_DEFINE_DYNAMIC_FUNC4(HuffTools_obj,make,return )


HuffTools_obj::HuffTools_obj()
{
}

void HuffTools_obj::__Mark(HX_MARK_PARAMS)
{
	HX_MARK_BEGIN_CLASS(HuffTools);
	HX_MARK_END_CLASS();
}

void HuffTools_obj::__Visit(HX_VISIT_PARAMS)
{
}

Dynamic HuffTools_obj::__Field(const ::String &inName,bool inCallProp)
{
	switch(inName.length) {
	case 4:
		if (HX_FIELD_EQ(inName,"make") ) { return make_dyn(); }
		break;
	case 8:
		if (HX_FIELD_EQ(inName,"treeWalk") ) { return treeWalk_dyn(); }
		if (HX_FIELD_EQ(inName,"treeMake") ) { return treeMake_dyn(); }
		break;
	case 9:
		if (HX_FIELD_EQ(inName,"treeDepth") ) { return treeDepth_dyn(); }
		break;
	case 12:
		if (HX_FIELD_EQ(inName,"treeCompress") ) { return treeCompress_dyn(); }
	}
	return super::__Field(inName,inCallProp);
}

Dynamic HuffTools_obj::__SetField(const ::String &inName,const Dynamic &inValue,bool inCallProp)
{
	return super::__SetField(inName,inValue,inCallProp);
}

void HuffTools_obj::__GetFields(Array< ::String> &outFields)
{
	super::__GetFields(outFields);
};

static ::String sStaticFields[] = {
	String(null()) };

static ::String sMemberFields[] = {
	HX_CSTRING("treeDepth"),
	HX_CSTRING("treeCompress"),
	HX_CSTRING("treeWalk"),
	HX_CSTRING("treeMake"),
	HX_CSTRING("make"),
	String(null()) };

static void sMarkStatics(HX_MARK_PARAMS) {
};

static void sVisitStatics(HX_VISIT_PARAMS) {
	HX_VISIT_MEMBER_NAME(HuffTools_obj::__mClass,"__mClass");
};

Class HuffTools_obj::__mClass;

void HuffTools_obj::__register()
{
	Static(__mClass) = hx::RegisterClass(HX_CSTRING("format.tools.HuffTools"), hx::TCanCast< HuffTools_obj> ,sStaticFields,sMemberFields,
	&__CreateEmpty, &__Create,
	&super::__SGetClass(), 0, sMarkStatics, sVisitStatics);
}

void HuffTools_obj::__boot()
{
}

} // end namespace format
} // end namespace tools
